﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Xml.Linq;
using C1.Phone;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Tasks;
using System.IO;
using System.Collections;

namespace ControlExplorer
{
    public partial class TileListBoxSample : UserControl
    {
        public TileListBoxSample()
        {
            InitializeComponent();

            if (!TiltEffect.TiltableItems.Contains(typeof(C1ListBoxItem)))
                TiltEffect.TiltableItems.Add(typeof(C1ListBoxItem));
            TiltEffect.SetIsTiltEnabled(this, true);

            LoadVideos();
        }

        private void LoadVideos()
        {
            try
            {
                loading.Visibility = Visibility.Visible;
                listBox.Visibility = Visibility.Collapsed;
                retry.Visibility = Visibility.Collapsed;
                var feed = new YoutubeFeed();
                feed.BeginLoadMoreItems(50, new AsyncCallback(ar =>
                    {
                        try
                        {
                            var videos = feed.EndLoadMoreItems(ar, Dispatcher);
                            Dispatcher.BeginInvoke(() =>
                                {
                                    listBox.ItemsSource = feed;
                                    loading.Visibility = Visibility.Collapsed;
                                    listBox.Visibility = Visibility.Visible;
                                    retry.Visibility = Visibility.Collapsed;
                                });
                        }
                        catch
                        {
                            Dispatcher.BeginInvoke(() =>
                                {
                                    MessageBox.Show("There was an error when attempting to download data from you tube.");
                                    loading.Visibility = Visibility.Collapsed;
                                    retry.Visibility = Visibility.Visible;
                                });
                        }
                    }), null);
            }
            catch
            {
                MessageBox.Show("There was an error when attempting to download data from you tube.");
                loading.Visibility = Visibility.Collapsed;
                retry.Visibility = Visibility.Visible;
            }
        }

        private void listBox_ItemTapped(object sender, C1TappedEventArgs e)
        {
            var video = (sender as C1ListBoxItem).Content as Video;
            NavigateUrl(video.Link);
            e.Handled = true;
        }

        public void NavigateUrl(string url)
        {
            try
            {
                var task = new WebBrowserTask();
                task.Uri = new Uri(url, UriKind.Absolute);
                task.Show();
            }
            catch { }
        }

        private void Retry_Click(object sender, RoutedEventArgs e)
        {
            LoadVideos();
        }
    }

    public class YoutubeFeed : IncrementalLoadingBase
    {
        private bool _hasMoreItems = true;
        private uint _lastIndex = 0;

        protected override IAsyncResult BeginLoadMoreItemsOverride(uint count, AsyncCallback callback, object state)
        {
            return BeginLoadVideos(_lastIndex + 1, Math.Min(count, 500 - _lastIndex), callback, state);
        }

        protected override IList<object> EndLoadMoreItemsOverride(IAsyncResult ar)
        {
            var videos = EndLoadVideos(ar);
            _lastIndex += (uint)videos.Count;
            _hasMoreItems = _lastIndex < 500;
            return videos.Cast<object>().ToList();
        }

        protected override bool HasMoreItemsOverride()
        {
            return _hasMoreItems;
        }

        private IAsyncResult BeginLoadVideos(uint startIndex, uint maxResults, AsyncCallback callback, object state)
        {
            var youtubeUrl = string.Format("https://gdata.youtube.com/feeds/api/videos?q=windows+8&start-index={0}&max-results={1}", startIndex, maxResults);
            var client = WebRequest.CreateHttp(new Uri(youtubeUrl));
            try
            {
                return client.BeginGetResponse(callback, client);
            }
            catch (WebException exc)
            {
                var excText = new StreamReader(exc.Response.GetResponseStream()).ReadToEnd();
                throw;
            }
        }

        private IList<Video> EndLoadVideos(IAsyncResult ar)
        {
            var AtomNS = "http://www.w3.org/2005/Atom";
            var MediaNS = "http://search.yahoo.com/mrss/";
            var videos = new List<Video>();

            var request = ar.AsyncState as HttpWebRequest;
            var response = request.EndGetResponse(ar);
            #region ** parse you tube data
            var doc = XDocument.Load(response.GetResponseStream());
            foreach (var entry in doc.Descendants(XName.Get("entry", AtomNS)))
            {
                var title = entry.Element(XName.Get("title", AtomNS)).Value;
                var thumbnail = "";
                var group = entry.Element(XName.Get("group", MediaNS));
                var thumbnails = group.Elements(XName.Get("thumbnail", MediaNS));
                var thumbnailElem = thumbnails.FirstOrDefault();
                if (thumbnailElem != null)
                    thumbnail = thumbnailElem.Attribute("url").Value;
                var alternate = entry.Elements(XName.Get("link", AtomNS)).Where(elem => elem.Attribute("rel").Value == "alternate").FirstOrDefault();
                var link = alternate.Attribute("href").Value;
                videos.Add(new Video() { Title = title, Link = link, Thumbnail = thumbnail });
            }
            #endregion
            return videos;
        }
    }

    public class Video
    {
        public string Title { get; set; }
        public string Thumbnail { get; set; }
        public string Link { get; set; }
    }
}
